//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "UI/Resources/UILocaleResource.h"
#include "UI/Resources/UILocaleSettingsResource.h"

namespace Engine
{
namespace UI
{

	//
	// Localization Manager
	//

	class LocaleManager : public BaseObject
	{
	// types
	public:
		typedef uint	StringID_t;		// 2 bytes to file ID, 2 bytes to string ID

	private:
		typedef map< StringID_t, ext_string >	locale_string_map_t;

		enum
		{
			FILE_ID_MASK	= 0xFFFF,
			FILE_ID_OFFSET	= 16,

			STR_ID_MASK		= 0xFFFF,
			STR_ID_OFFSET	= 0,
		};


	// variables
	private:
		UILocaleSettingsResourcePtr		_settings;
		locale_string_map_t				_strings;
		string							_filepath;
		uint							_currentLocale;
		LocaleCharacters				_localeChars;


	// methods
	public:
		LocaleManager (const EngineSubSystemsRef ess);
		~LocaleManager ();

		bool Load (uni_c_string filename);
		bool SetLocalePath (uni_c_string path);
		void Clear ();

		bool IsLanguageSupported (uni_c_string iso3Name) const;
		bool SetCurrentLanguage (uni_c_string iso3Name);

		bool GetString (StringID_t id, OUT string &str);
		bool GetString (StringID_t id, OUT ext_string &str);

		string const &	GetCurrentLanguage () const;
		string const &	GetCurrentLanguageISO3 () const;

		LocaleCharacters const &	GetLocaleUtils () const		{ return _localeChars; }


	private:
		bool _GetStringIndex (StringID_t id, OUT usize &index);

		bool _LoadLocaleResource (uint fileID);

		static StringID_t _BuildStringID (uint fileID, uint strID);
		static uint _GetStringID (StringID_t id);
		static uint _GetFileID (StringID_t id);
	};
	

	

/*
=================================================
	GetString
=================================================
*/
	inline bool LocaleManager::GetString (StringID_t id, OUT string &str)
	{
		if ( id == 0 )
			return true;

		usize	i = -1;
		CHECK_ERR( _GetStringIndex( id, i ) );

		_strings[i].second.ExtractString( str );

		ASSERT( not str.Empty() );
		return true;
	}
	
/*
=================================================
	GetString
=================================================
*/
	inline bool LocaleManager::GetString (StringID_t id, OUT ext_string &str)
	{
		if ( id == 0 )
			return true;

		usize	i = -1;
		CHECK_ERR( _GetStringIndex( id, i ) );

		str = _strings[i].second;
		ASSERT( not str.Empty() );
		return true;
	}
	
/*
=================================================
	_GetStringIndex
=================================================
*/
	inline bool LocaleManager::_GetStringIndex (StringID_t id, OUT usize &index)
	{
		//ASSERT( id != 0 );

		if ( not _strings.FindIndex( id, index ) )
		{
			if ( not _LoadLocaleResource( _GetFileID( id ) ) or
				 not _strings.FindIndex( id, index ) )
			{
				return false;
			}
		}
		return true;
	}
	
/*
=================================================
	GetCurrentLanguage
=================================================
*/
	inline string const & LocaleManager::GetCurrentLanguage () const
	{
		return _settings->GetLanguages()[ _currentLocale ].name;
	}
	
/*
=================================================
	GetCurrentLanguageISO3
=================================================
*/
	inline string const & LocaleManager::GetCurrentLanguageISO3 () const
	{
		return _settings->GetLanguages()[ _currentLocale ].iso3Name;
	}
	
/*
=================================================
	SetLocalePath
=================================================
*/
	inline bool LocaleManager::SetLocalePath (uni_c_string path)
	{
		CHECK_ERR( ESS()->GetFileSystem()->IsDirectoryExist( path ) );

		_filepath = path;
		return true;
	}

/*
=================================================
	_BuildStringID
=================================================
*/
	inline LocaleManager::StringID_t LocaleManager::_BuildStringID (uint fileID, uint strID)
	{
		return	( ( fileID & FILE_ID_MASK ) << FILE_ID_OFFSET ) |
				( ( strID  & STR_ID_MASK  ) << STR_ID_OFFSET  );
	}
	
/*
=================================================
	_GetStringID
=================================================
*/
	inline uint LocaleManager::_GetStringID (StringID_t id)
	{
		return ( ( id >> STR_ID_OFFSET ) & STR_ID_MASK );
	}
	
/*
=================================================
	_GetFileID
=================================================
*/
	inline uint LocaleManager::_GetFileID (StringID_t id)
	{
		return ( ( id >> FILE_ID_OFFSET ) & FILE_ID_MASK );
	}


}	// UI
}	// Engine
